#define REDIS_IP "127.0.0.1"
#define REDIS_PORT "6379"

#include "CacheUtils.h"
#include "LogUtils.h"
#include <memory>
#include <iostream>
#include <vector>
#include <string>
#include <sw/redis++/redis++.h>
using std::shared_ptr;
using std::cout;
using std::endl;
using std::cerr;
using std::string;
using std::vector;
using namespace sw::redis;

// 获取实例
CacheUtils& CacheUtils::getInstance(){
    static CacheUtils instance;
    return instance;
}

// 构造函数
CacheUtils::CacheUtils()
: m_redis(std::make_shared<Redis>("tcp://127.0.0.1:6379")){
}

/**
 * @brief 添加推荐系统的缓存项。
 * @param key 缓存键 (e.g., "recommender:query")
 * @param value 待缓存的 JSON 数据
 * @return true 如果设置成功，否则 false
 */
bool CacheUtils::addKeyRecommanderCache(const string &key, const json &value){
    // 构造完整的 Key，例如 "rc:query:linux"
    string full_key = RECOMMENDER_PREFIX + key;

    vector<string> vecCandidate;
    for(auto &ele: value){
        vecCandidate.push_back(ele);
    }

    try{
        m_redis->rpush(full_key,vecCandidate.begin(),vecCandidate.end());
    }catch(const sw::redis::Error &e){
        LOG_INFO << "[addKeyRecommanderCache]" << e.what();
        return false;
    }

    return true;
}

/**
 * @brief 添加搜索引擎服务的缓存数据。
 * @param key 缓存键 (e.g., "search:result:keyword")
 * @param value 待缓存的 JSON 数据
 * @return true 如果设置成功，否则 false
 */
bool CacheUtils::addWebPageSearcherCache(const string &key, const json &value){
    // 构造完整的 Key，例如 "rc:query:linux"
    string full_key = SEARCHER_PREFIX + key;

    vector<string> vecWebInfo;
    for(auto &e: value){
        vecWebInfo.push_back(e.dump());
    }

    try{
        m_redis->rpush(full_key,vecWebInfo.begin(),vecWebInfo.end());
    }catch(const sw::redis::Error &e){
        LOG_INFO << "[addWebPageSearcherCache]" << e.what();
        return false;
    }

    return true;
}

/**
 * @brief 获取推荐系统的缓存项。
 * @param key 缓存键
 * @return 包含 JSON 数据的 std::optional 对象。如果缓存未命中或解析失败，则返回 std::nullopt。
 */
optional<json> CacheUtils::getKeyRecommanderCache(const string &key){
    string full_key = RECOMMENDER_PREFIX + key;

    vector<string> elems;
    m_redis->lrange(full_key, 0, -1, std::back_inserter(elems));

    json j = json::array();
    for (const auto &e : elems) {
        j.push_back(e);
    }

    if(elems.empty()){
        return std::nullopt;
    }

    return j;
}

/**
 * @brief 获取搜索引擎服务的缓存数据。
 * @param key 缓存键
 * @return 包含 JSON 数据的 std::optional 对象。如果缓存未命中或解析失败，则返回 std::nullopt。
 */
optional<json> CacheUtils::getWebPageSearcherCache(const string &key){
    string full_key = SEARCHER_PREFIX + key;

    vector<string> elems;
    m_redis->lrange(full_key, 0, -1, std::back_inserter(elems));

    json j = json::array();
    for (const auto &e : elems) {
        j.push_back(json::parse(e));
    }

    //LOG_INFO << j.dump();
    if(elems.empty()){
        return std::nullopt;
    }

    return j;
}

// [可选] 获取连接的方法 (如果需要直接操作 Redis)
Redis& CacheUtils::getRedisConnection(){
    return *m_redis;
}